﻿using System;
using System.IO;
using System.Windows.Forms;
using DigitalRune.Windows.TextEditor;
using DigitalRune.Windows.TextEditor.Actions;
using DigitalRune.Windows.TextEditor.Completion;
using DigitalRune.Windows.TextEditor.Highlighting;
using DigitalRune.Windows.TextEditor.Selection;
using FunctionalCLR.Core;
using FunctionalCLR.Core.Function;
using Zove.Runtime;

namespace Zove.Desktop {
    public partial class EditingForm : AbstractDesktopForm {
        public string ClassName {
            get;
            set;
        }

        public RunWindow RunningInstance {
            get;
            set;
        }

        public void ContextMenuItem_OnClick(object sender, EventArgs args) {
            if (base.Selections.Count < 1) {
                return;
            }

            ISelection selection = base.Selections[0];
            if (selection.Offset < 
                this.GetTextEditorControl().Text.Length
                && this.GetTextEditorControl().Text[
                selection.EndOffset] == '(') {
                // show 

                string summary = string.Empty;
                FuncNode fn = ZoveDependencyManager.Instance.FunctionManager.Get(
                    selection.SelectedText);
                if (fn == null) {
                } else if (fn is UserDefinedFunctionNode) {
                    UserDefinedFunctionNode udf
                        = (UserDefinedFunctionNode)fn;
                    summary = udf.Comment;
                    if (string.IsNullOrEmpty(summary)) {
                        MessageBox.Show("The summary for the function is left blank");
                    } else {
                        MessageBox.Show(summary);
                    }
                } else {
                    string helpFileName
                        = ZoveDependencyManager.GetFileFile(
                        selection.SelectedText);
                    if (helpFileName != null) {
                        if (File.Exists(helpFileName)) {
                            HelpWindow hw = new HelpWindow(helpFileName);

                            ((Form1)this.MdiParent).ShowWindow(hw);
                        } else {
                            MessageBox.Show("Cannot find the correpsonded help text for function " + selection.SelectedText);
                        }
                    } else {
                        MessageBox.Show(
                            "Cannot find correpsonded help text for function "
                            + selection.SelectedText);
                    }
                }
            } else {
                ((Form1)this.MdiParent).OpenEditWindow(base.SelectedText);
            }
        }

        public EditingForm()
            : base() {
            ContextMenu menu = this.GetTextEditorControl().ContextMenu;
            menu.MenuItems.Add(new MenuItem(
                "&Go To Definition",
                new EventHandler(ContextMenuItem_OnClick)));
            menu.MenuItems.Add(new MenuItem(
                 "Cut",
                 new EventHandler(Cut)));
            menu.MenuItems.Add(new MenuItem(
                 "&Copy",
                 new EventHandler(Copy)));
            menu.MenuItems.Add(new MenuItem(
                 "&Paste",
                 new EventHandler(Paste)));
            menu.MenuItems.Add(new MenuItem(
                 "&Delete",
                 new EventHandler(Delete)));

            this.GetTextEditorControl().Document.HighlightingStrategy
                = HighlightingManager.Manager.FindHighlighter("Zoom");
        }

        public void Cut(object sender, EventArgs args) {
            Cut cut = new Cut();
            cut.Execute(this.GetTextEditorControl());
        }

        public void Copy(object sender, EventArgs args) {
            Copy cut = new Copy();
            cut.Execute(this.GetTextEditorControl());
        }

        public void Paste(object sender, EventArgs args) {
            Paste cut = new Paste();
            cut.Execute(this.GetTextEditorControl());
        }

        public void Delete(object sender, EventArgs args) {
            Delete cut = new Delete();
            cut.Execute(this.GetTextEditorControl());
        }

        public EditingForm(string fileName)
            : this() {
            this.ClassName = GetClassName(fileName);
            this.FileName = fileName;
            this.Text = fileName;
            this.GetTextEditorControl().Document.TextContent = File.ReadAllText(fileName);
            base.IsDirty = false;
        }

        public override string GetFileExtension() {
            return ".zoom";
        }

        private void CompletionRequest(object sender, CompletionEventArgs e) {
            if (this.GetTextEditorControl().CompletionWindowVisible) {
                return;
            }

            if (e.Key == '\0') {
                this.GetTextEditorControl().ShowCompletionWindow(
                    new CodeCompletionDataProvider(), e.Key, false);
            } else if (char.IsLetter(e.Key)) {
                this.GetTextEditorControl().ShowCompletionWindow(
                    new CodeCompletionDataProvider(), e.Key, true);
            }
        }


        public static string GetClassName(string fileName) {
            int lastDot = fileName.LastIndexOf('.');
            if (lastDot > 0) {
                int last = fileName.LastIndexOf('\\');
                return fileName.Substring(last + 1, lastDot - last - 1);
            }

            return fileName;
        }

        public void Export(string fileName) {
        }

        public Zove.Compiler.ZoomClass Class {
            get {
                Zove.Runtime.DefaultClassLoader cl
                    = new Zove.Runtime.DefaultClassLoader();
                Zove.Compiler.ZoomClass c = cl.LoadFromSource(this.Source);

                return c;
            }
        }

        public override void Execute() {
            try {
                if (this.RunningInstance == null) {
                    this.RunningInstance = new RunWindow(Class);
                    this.RunningInstance.MdiParent = this.MdiParent;
                    this.RunningInstance.Editor = this;
                    this.RunningInstance.FormClosing
                        += new FormClosingEventHandler(
                            ((Form1)this.MdiParent).RemoveWindowItem);
                    this.RunningInstance.Show();
                } else {
                    this.RunningInstance.BringToFront();
                }

                ((Form1)this.MdiParent).AddWindowMenuItem(
                    this.RunningInstance, WindowType.Run);
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }

        public override TextEditorControl GetTextEditorControl() {
            return this.teSource;
        }

        public override string GetFileFilter() {
            return "Zoom file (*.zoom) | *.zoom |HTML file (*.html) | *.html";
        }

        public override string GetColouringScheme() {
            return "Zoom";
        }
    }
}
